
* THIS PROGRAM ACCEPTS AN ASCII SOURCE FILE
* ASSUMED TO BE IN THE FORM OF A SOMEWHAT
* STANDARD DEC FUNCTIONAL SPECIFICATION AND
* CONVERTS IT INTO A FILE WHICH CAN BE PROCESSED
* BY CLEMENT'S RUNOFF PROGRAM.  IT ASSUMES THAT
* EVERY PARAGRAPH IS NUMBERED.  IT WILL PRECEED
* THE BEGINNING OF EVERY SENTENCE WITH '^', IT
* WILL CAPITALIZE EACH WORD OF A PARAGRAPH
* HEADER LINE, IT WILL CAPITALIZE KEYWORDS, AND
* GENERATE .INDEX STATEMENTS WHERE
* DESIRED BY THE USER.  IT WILL ALSO MAKE
* AN ATTEMPT TO PRESERVE THE ESSENTIAL CHARACTER
* OF FIGURES AND DIAGRAMS.
*
* L. P. WADE  12-15-70

	TAB = '	'
	BLANK = ' '
	DIGITS = '0123456789'
	ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
	DEFAULTMARGIN = 10

	&TRIM = 1
	&ERRLIMIT = 1
	&ANCHOR = 1
	TRACE('OUT',,'WROTE','WATCH')
	TRACE('ERRTYPE','KEYWORD','ERROR','KILL')

	DEFINE('KILL(NAME,TAG)')	:(KEND)
KILL	TYPE = TAG ' ' $NAME
	TYPE = 'CLOSING OUTPUT AND QUITTING'	:(EOF)
KEND

	DEFINE('WATCH(NAME,TAG)')	:(WEND)
WATCH	OUTPUT = TAG ' ' $NAME	:(RETURN)
WEND


	ALWAYS = 'UFD' ! 'RC11' ! 'RK11' !
+ 'TTY' ! 'DEC' ! 'PC11' ! 'LP11' ! 'ROM' !
+ 'PDP' ! 'ASR' ! 'DOS' ! 'PDP-' ! 'ASR-'

INIT	LMARG = DEFAULTMARGIN

	OUTPUT('TYPE',2,'(1X,16A5)')
	INPUT('ACCEPT',2,80)

	OUTPUT('OUT',21,'(1X,27A5)')
	INPUT('IN',20,80)	:(GETIN)
BADIN	TYPE = 'INPUT FILE NOT THERE STUPID'
GETIN	TYPE = 'INPUT FILENAME: '
	INNAM = ACCEPT
	IFILE(20,INNAM)		:F(BADIN)

	TYPE = 'OUTPUT FILENAME: '
	OUTNAM = ACCEPT
	OFILE(21,OUTNAM)

GETKEY	TYPE = 'KEYWORD FILENAME: '
	KEYNAM = ACCEPT
	IDENT(KEYNAM)		:S(GETI)
	IFILE(22,KEYNAM)	:F(GETKEY)
GETI
	INPUT('KEY',22,80)

* BUILD UP THE KEYWORD PATTERN

	IDENT(KEYNAM)		:S(KEYEND)
	KEYPAT = 'LARRY'
KEYLOOP	T = KEY			:F(KEYEND)
	KEYPAT = T ' ! ' KEYPAT	:(KEYLOOP)
KEYEND


	&TRACE = 0

-EJECT

* DEFINE A PARAGRAPH NUMBER AS A STRING OF
* DIGITS WITH PERIODS INSIDE, I.E. 3.1 OR 3.5.1.6.2

	PNUM = SPAN(DIGITS '.')

* DEFINE FILL AS A SPAN OF BLANKS OR TABS.

	FILL = SPAN(BLANK TAB)
	SPACE = BLANK TAB

	DEFINE('CAPSENTENCE(S)N')

* THIS FUNCTION WILL ACCEPT A STRING AS INPUT AND
* RETURN THE SAME STRING WITH THE FIRST LETTER OF
* EVERY SENTENCE CAPITALIZED.

	SENTENCEPAT = POS(*N) . A BREAK('.') . B
+ FILL . C @N REM . D
				:(SENTEND)

CAPSENTENCE	N = 0

CAPSEN	S SENTENCEPAT = A B C '^' D
+	:S(CAPSEN)F(RETURN)
SENTEND

	DEFINE('CAPALL(S)N')

* THIS FUNCTION WILL ACCEPT A STRING AS INPUT AND
* REUTRN THE SAME STRING WITH THE FIRST LETTER OF ALL WORDS CAPITALIZED.
*
* 'WORDS' ARE DEFINED AS ANY SYMBOL STRING FOLLOWING A
* SPAN OF BLANKS OR TABS.

	CAPPAT = POS(*N) . A  ARB . B
+ NOTANY(SPACE) . LETTER @N REM . C
				:(CAPEND)

CAPALL	N = 0

CAPALL1	S  CAPPAT = A B '^' LETTER C  :S(CAPALL1)F(RETURN)
CAPEND

* MAKE SURE ALL RESERVED WORDS ARE ALL CAPITALIZED

	DEFINE('CAPS(S)N')

	RESPAT = (POS(*N) FILL) . A ALWAYS . B
+	(FILL ! NULL) . C  @N  REM . D	:(RESEND)

CAPS	N = 0
CAPS1	S RESPAT = A '^^' B '\\' C D :S(CAPS1)F(RETURN)
RESEND

	DEFINE('CAPFIRST(S)N')

* THIS FUNCTION WILL ACCEPT A STRING AS INPUT AND
* RETURN THE SAME STRING WITH THE FIRST LETTER OF
* THE FIRST WORD CAPITALIZED.  IT TAKES INTO ACCOUNT
* THE POSSIBILITY THAT THE LINE MAY HAVE A LEADING
* PARAGRAPH NUMBER.

	FIRSTPAT = (NULL ! (PNUM FILL)) . A
+	NOTANY(SPACE) . LETTER REM . B  :(FIRSTEND)

CAPFIRST	S FIRSTPAT = A '^' LETTER B  :(RETURN)
FIRSTEND

	DEFINE('KEYWORD(S)')

	KPAT = (POS(*N) FILL) . A KEYPAT . B (FILL ! NULL) . C
+		@N  REM . D	:(DEFKEY)

KEYWORD	N = 0
KEYW1	S  KPAT = A '^' B C D :S(KEYW1)F(RETURN)
DEFKEY


-EJECT

* BEHOLD THE MAIN LOOP!
*
* READ A LINE FROM THE INPUT STREAM, AND CHECK FOR END OF FILE

NEWLINE	T = IN			:F(EOF)

* CHECK IF THIS LINE IS THE BEGINNING OF A NEW
* PARAGRAPH, THAT IS DOES IT BEGIN WITH A
* PARAGRAPH NUMBER?

	T POS(0) PNUM		:S(NEWPAR)

* CHECK TO SEE IF THIS IS A NULL LINE, EITHER EMPTY
* OR CONTAINING ONLY BLANKS AND TABS.

	IDENT(T)		:S(EMPTY)
*	T NOTANY(SPACE)		:F(EMPTY)

* CHECK FOR THE SPECIAL CASE OF BEING IN THE
* MIDST OF A FIGURE.  I WILL ATTEMPT TO IDENTIFY
* THIS BY SEEING IF THE FILL EXTENDS BEYOND
* THE LEFT MARGIN.  I WILL ALSO ASSUME THAT
* THE FILL CONSISTS ONLY OF BLANKS AND NO TABS.

	T NOTANY(BLANK) @N	:F(CHKTAB)
	GT(N,LMARG)		:S(STARTFIG)
CHKTAB	T NOTANY(TAB) @N :(NOFIGURE)
	N = N * 8
	GT(N,LMARG)	:S(STARTFIG)

NOFIGURE

* CHECK TO SEE IF THIS IS THE FIRST LINE SEEN SINCE
* THE HEADER WAS SEEN

	IDENT(HDFLAG)		:S(FIRSTLINE)

* NOW CAPITALIZE THE FIRST WORD OF EVERY SENTENCE

REJOIN	CAPSENTENCE(T)

* NOW MAKE ALL SPECIAL WORDS ALL CAPITALS

REJOIN1	KEYWORD(T)
	CAPS(T)

OUTIT	OUT = T			:(NEWLINE)

-EJECT

* THIS CODE HANDLES THE CASE OF A NEW PARAGRAPH.
* THE LINE IS ASSUMED TO BEGIN WITH A PARAGRAPH
* NUMBER.

* CAPITALIZE THE FIRST LETTER OF EVERY WORD

NEWPAR	CAPFIRST(T)

* OUTPUT SOME COMMANDS TO RUNOFF
	OUT = '.FILL';	OUT = '.JUSTIFY'
	OUT = '.BREAK'

* I ASSUME THE NUMBER OF SPACES BETWEEN THE PARAGRAPH
* NUMBER AND THE FIRST WORD ARE SIGNIFICANT SO I
* PRESERVE THEM WITH THE '#' FEATURE OF RUNOFF

	T (PNUM . A SPAN(BLANK) . N REM . C) =
+	A DUPL('#',SIZE(N)) C

* RECORD THE FACT THAT THE HEADER FOR THIS PARAGRAPH
* HAS BEEN SEEN

	HDFLAG = 1		:(REJOIN1)

* THIS CODE HANDLES THE CASE OF THE FIRST LINE
* AFTER THE BEGINNING OF A PARAGRAPH WHICH HAS TEXT.
* IT SETS THE MARGIN TO A DEFAULT VALUE IF
* THERE IS NO FILL, TO THE LENGTH OF SPAN OF BLANKS,
* OR ELSE SETS THE TAB STOPS IF THE SENTENCE BEGINS
* WITH THEM

FIRSTLINE	T FILL   @N GT(N - 1,1)
+				:F(DEFAULTIT)
	N = 0
	T SPAN(TAB) . N		:S(TABIT)
	T SPAN(BLANK) . N	:F(FIRSTCONT)
* SO MAKE THE MARGIN CORRESPOND TO THE NO. OF BLANKS.

	OUT = '.LMARG ' SIZE(N)	:(FIRSTCONT)

* THE LINE HAS TABS

	OUT = '.LMARG ' SIZE(N) * 10  :(FIRSTCONT)

* MAKE IT THE DEFAULT

DEFAULTIT	OUT = '.LMARG ' DEFAULTMARGIN
FIRSTCONT	HDFLAG =
		CAPSENTENCE(T)	:(OUTIT)

* THIS CODE ATTEMPTS TO PRESERVE THE ESSENCE OF
* FIGURES

STARTFIG	FIGFLAG = 1

* TAKE CARE TO PRESERVE ANY '#' SYMBOLS IN THE TEXT

	T '#' = '_#'

* NOW REPLACE ALL BLANKS WITH THE PROPER CHARACTER(#)

	REPLACE(T,BLANK,'#')

* REPLACE ALL TABS WITH 8 #S
	TABPAT = BREAK(TAB) . A TAB REM . B
	N = 0
TAB1	T TABPAT = A   '########' B :S(TAB1)

* NOW GUARD AGAINST FILLING AND JUSTIFYING

	OUT = '.NOFILL'
	OUT = '.NOJUSTIFY'		:(OUTIT)

* THIS CODE HANDLES THE CASE OF A NULL LINE.

EMPTY	OUT = '.SKIP'
	EMFLAG = 1		:(NEWLINE)

* CLEANUP THE OUTPUT FILE AND SAY GOODBY

EOF	OUT = '.PAGE'

	ENDFILE(21)
	TYPE = 'DONE'
	KEYWORD()
END
  